package com.sen.uaa.config;

import com.sen.uaa.logout.OauthLogoutHandler;
import com.sen.uaa.logout.OauthLogoutSuccessHandler;
import com.sen.uaa.logout.SuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import javax.annotation.Resource;

/**
   * @Description 管理账户
   * @Author esJiang
**/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Resource
    private UserDetailsService userService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder() ;
    }

    /**
     * @Description 密码模式必须
     * @Author esjiang
     **/
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     *  配置用户信息和加密方式;用户信息可以直接在内存中定义也可以在db中配置，本方法是基于db
     **/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/favor.ioc");
        web.ignoring().antMatchers("/actuator/**") ;
    }

    @Bean
    public OauthLogoutHandler oauthLogoutHandler(){
        return new OauthLogoutHandler() ;
    }


    @Resource
    private OauthLogoutSuccessHandler oauthLogoutSuccessHandler ;

    @Resource
    private SuccessHandler successHandler ;

    @Resource
    private CaAuthenticationSecurityConfig caAuthenticationSecurityConfig ;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .and()
                .logout().permitAll()
                .logoutUrl("/oauth/remove/token")
                .logoutSuccessHandler(oauthLogoutSuccessHandler)
                .addLogoutHandler(oauthLogoutHandler()).clearAuthentication(true)
                .and()
                .apply(caAuthenticationSecurityConfig)

        .and().csrf().disable()
        ;
        // 授权码模式单独处理，需要session的支持，此模式可以支持所有oauth2的认证
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
    }
}
